package com.fb.common;

import com.fb.model.SessionModel;
import com.fb.model.UserModel;
import hapax.Template;
import hapax.TemplateDataDictionary;
import hapax.TemplateDictionary;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.Normalizer;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.digest.DigestUtils;
import org.json.simple.JSONObject;

/**
 *
 * @author vuln2
 */
public class CommonUtil {

    public static final byte HEADER_HTML = 0;
    public static final byte HEADER_JS = 1;

    public static String getHeader() throws Exception {
        TemplateDataDictionary headerVariable = TemplateDictionary.create();
        Template template = RenderModel.getCTemplate("block_header");
        return template.renderToString(headerVariable);
    }

    public static String getFooter() throws Exception {
        TemplateDataDictionary footerVariable = TemplateDictionary.create();
        Template template = RenderModel.getCTemplate("block_footer");
        return template.renderToString(footerVariable);
    }

    public static String getMenu(HttpServletRequest req) throws Exception {
        TemplateDataDictionary menuVariable = TemplateDictionary.create();
        SessionModel sessionModel = SessionModel.getInstance();
        menuVariable.setVariable("USERNAME", sessionModel.getUserLogin(req));
        Template template = RenderModel.getCTemplate("block_menu");
        return template.renderToString(menuVariable);
    }

    public static String getAdminHeader() throws Exception {
        String content;
        TemplateDataDictionary headerVariable = TemplateDictionary.create();
        headerVariable.setVariable("SITE_TITLE", ConfigFactory.getParam("static", "admin_app_name"));
        Template template = RenderModel.getAdminCTemplate("block_header");
        content = template.renderToString(headerVariable);
        return content;
    }

    public static String getAdminFooter() throws Exception {
        String content;
        TemplateDataDictionary footerVariable = TemplateDictionary.create();
        Template template = RenderModel.getAdminCTemplate("block_footer");
        content = template.renderToString(footerVariable);
        return content;
    }

    public static String getAdminMenu(HttpServletRequest req) throws Exception {
        String content;
        TemplateDataDictionary menuVariable = TemplateDictionary.create();
        menuVariable.setVariable("SITE_TITLE", ConfigFactory.getParam("static", "admin_app_name"));
        SessionModel sessionModel = SessionModel.getInstance();
        menuVariable.setVariable("USERNAME", sessionModel.getUserLogin(req));
        if (isAdmin(req)) {
            menuVariable.showSection("USER_CONTROL");
        }
        Template template = RenderModel.getAdminCTemplate("block_menu");
        content = template.renderToString(menuVariable);
        return content;
    }

    public static String getAdminSidebar(HttpServletRequest req, String pos) throws Exception {
        String content;
        TemplateDataDictionary sidebarVariable = TemplateDictionary.create();
        switch (pos) {
            case "post_list":
                sidebarVariable.showSection("PROFILE");
                sidebarVariable.showSection("POST_LIST");
                break;
            case "profile_list":
            case "profile_edit":
            case "post_add":
            case "post_edit":
                sidebarVariable.showSection("PROFILE");
                sidebarVariable.showSection("PROFILE_LIST");
                break;
            case "profile_add":
                sidebarVariable.showSection("PROFILE");
                sidebarVariable.showSection("PROFILE_ADD");
                break;
            case "profile_cate":
                sidebarVariable.showSection("PROFILE_CATE");
                sidebarVariable.showSection("CATEGORY_LIST");
                sidebarVariable.showSection("CATE_MENU");
                break;
            case "news_cate":
                sidebarVariable.showSection("NEWS_CATE");
                sidebarVariable.showSection("CATEGORY_LIST");
                sidebarVariable.showSection("CATE_MENU");
                break;
            case "news_edit": 
                sidebarVariable.showSection("NEWS_MENU");
                sidebarVariable.showSection("NEWS_LIST");                
                break;
            case "news_add":
                sidebarVariable.showSection("NEWS_MENU");
                sidebarVariable.showSection("NEWS_ADD");                
                break;
        }

        SessionModel sessionModel = SessionModel.getInstance();
        String userLogin = sessionModel.getUserLogin(req);
        UserModel userModel = UserModel.getInstance();
        UserData account = userModel.getUserByName(userLogin);
        if(account != null) {
            List<String> lstAccess = account.getAccess();
            boolean isAdmin = account.type.getId() == UserType.ADMIN.getId();
            for (UserRole role : EnumSet.allOf(UserRole.class)) {
                String id = role.getRole();
                switch (id) {
                    case "1":
                        if (lstAccess.contains(id) || isAdmin) {
                            sidebarVariable.showSection("SIDEBAR_PROFILE");
                        }
                        break;
                    case "1.1":
                        if (lstAccess.contains(id) || isAdmin) {
                            sidebarVariable.showSection("SIDEBAR_PROFILE_ADD");
                        }
                        break;
                    case "3":
                        if (lstAccess.contains(id) || isAdmin) {
                            sidebarVariable.showSection("SIDEBAR_CATEGORY");
                        }
                        break;
                    case "7":
                        if (lstAccess.contains(id) || isAdmin) {
                            sidebarVariable.showSection("SIDEBAR_NEWS");
                        }
                        break;
                    case "7.1":
                        if (lstAccess.contains(id) || isAdmin) {
                            sidebarVariable.showSection("SIDEBAR_NEWS_ADD");
                        }
                        break;    
                }
            }
        }
        Template template = RenderModel.getAdminCTemplate("block_sidebar");
        content = template.renderToString(sidebarVariable);
        return content;
    }

    public static String md5(String pass) {
        try {
            return DigestUtils.md5Hex(pass);
        } catch (Exception ex) {
        }
        return "";
    }

    public static String toJSON(int error, String msg) {
        Map mapdata = new HashMap();
        JSONObject ldata = new JSONObject();
        mapdata.put("err", error);
        mapdata.put("msg", msg);
        ldata.putAll(mapdata);
        return ldata.toJSONString();
    }

    public static String toJSON(int error, String msg, String data) {
        Map mapdata = new HashMap();
        JSONObject ldata = new JSONObject();
        mapdata.put("err", error);
        mapdata.put("msg", msg);
        mapdata.put("data", data);
        ldata.putAll(mapdata);
        return ldata.toJSONString();
    }

    public static String toJSON(int error, String msg, Map data) {
        Map mapdata = new HashMap();
        JSONObject ldata = new JSONObject();
        mapdata.put("err", error);
        mapdata.put("msg", msg);
        mapdata.put("data", data);
        ldata.putAll(mapdata);
        return ldata.toJSONString();
    }

    public static String toJSON(int error, String msg, List<Map> data) {
        Map mapdata = new HashMap();
        JSONObject ldata = new JSONObject();
        mapdata.put("err", error);
        mapdata.put("msg", msg);
        mapdata.put("data", data);
        ldata.putAll(mapdata);
        return ldata.toJSONString();
    }

    public static String toPermissionDenied() {
        int error = -1;
        String msg = "Không có quyền truy cập.";
        JSONObject ldata = new JSONObject();
        ldata.put("err", error);
        ldata.put("msg", msg);
        return ldata.toJSONString();
    }

    public static void out(String content, HttpServletResponse respon) throws IOException {
        PrintWriter out = respon.getWriter();
        out.print(content);
    }

    public static void prepareHeader(HttpServletResponse resp, byte type) {
        resp.setCharacterEncoding("utf-8");
        if (type == HEADER_HTML) {
            resp.setContentType("text/html; charset=utf-8");
        } else if (type == HEADER_JS) {
            resp.setContentType("text/javascript; charset=utf-8");
        }
        String appName = ConfigFactory.getParam("rest", "app_name");
        resp.addHeader("Server", appName);
    }

    public static boolean checkSession(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String pathInfo = (req.getPathInfo() == null) ? "" : req.getPathInfo();
        SessionModel sessionModel = SessionModel.getInstance();
        if (!pathInfo.startsWith("/login") && sessionModel.getUserLogin(req).equalsIgnoreCase("")) {
            resp.sendRedirect("/login");
            return false;
        }
        return true;
    }

    public static boolean checkAccess(HttpServletRequest req, UserRole userRole) {
        SessionModel sessionModel = SessionModel.getInstance();
        String userName = sessionModel.getUserLogin(req);
        if (userName == null || userName.equalsIgnoreCase("")) {
            return false;
        }
        UserModel userModel = UserModel.getInstance();
        UserData account = userModel.getUserByName(userName);

        if (account.getType().getId() == UserType.ADMIN.getId()) {
            return true;
        }

        if (account.getAccess() == null) {
            return false;
        }

        return account.getAccess().contains(userRole.getRole());
    }

    public static String getPageNavi(int current, int postCount, int postPerPage, String link) {
        Pattern p = Pattern.compile("-?\\d+");
        Matcher m = p.matcher(link);
        while (m.find()) {
            String tmp = m.group();
            link = link.replace("?p=" + tmp, "?")
                    .replace("&p=" + tmp, "");
        }
        if (link.lastIndexOf("?") == link.length() - 1) {
            link = link.replace("?", "");
        }

        String html = "";
        String paramDelimiter = link.contains("?") ? "&" : "?";
        if (postCount > postPerPage) {
            int totalPage = postCount / postPerPage + (postCount % postPerPage > 0 ? 1 : 0);
            int PAGEGAP = 3;
            String li = "";
            for (int i = 1; i <= totalPage; i++) {
                String pageNum;
                String url;
                if (i > 1 && i < totalPage && Math.abs(i - current) > PAGEGAP) {
                    i = i < current ? current - PAGEGAP : totalPage - 1;
                    pageNum = "...";
                    url = "#";
                } else {
                    pageNum = String.valueOf(i);
                    url = link + paramDelimiter + "p=" + i;
                }
                li += "<li class=\"" + (current == i ? "active" : "") + "\">"
                        + "<a href=\"" + url + "\">" + pageNum + "</a>"
                        + "</li>";
            }
            String firstPage = "<li class=\"" + (current == 1 ? "disabled" : "") + "\">"
                    + "<a href=\"" + link + paramDelimiter + "p=1\">&laquo;</a>"
                    + "</li>";
            String lastPage = "<li class=\"" + (current == totalPage ? "disabled" : "") + "\">"
                    + "<a href=\"" + link + paramDelimiter + "p=" + totalPage + "\">&raquo;</a>"
                    + "</li>";
            html = "<ul style=\"margin: 0;\" class=\"pagination pagination-md pull-right\">" + firstPage + li + lastPage + "</ul>";
        }
        return html;
    }

    public static BufferedImage convertPNGToJPG(BufferedImage bufferedImage) {
        BufferedImage newBufferedImage = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
        newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0, Color.WHITE, null);
        return newBufferedImage;
    }

    public static String URLFriendly(String input) {
        Pattern WHITESPACE = Pattern.compile("[\\s]");
        String nowhitespace = WHITESPACE.matcher(input).replaceAll("-");
        String normalized = Normalizer.normalize(nowhitespace, Normalizer.Form.NFD);
        Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
        //String slug = pattern.matcher(normalized).replaceAll("");
        String slug =  pattern.matcher(normalized).replaceAll("").replaceAll("Đ", "D").replace("đ", "d");
        return slug.toLowerCase(Locale.ENGLISH).replaceAll("(\\-)+", "-");                      
        //Pattern NONLATIN = Pattern.compile("[^\\w-]");        
    }

    public static boolean isAdmin(HttpServletRequest req) {
        SessionModel sessionModel = SessionModel.getInstance();
        String userLogin = sessionModel.getUserLogin(req);
        if (userLogin != null) {
            UserModel userModel = UserModel.getInstance();
            UserData userData = userModel.getUserByName(userLogin);
            if (userData != null) {
                return userData.getType().getId() == UserType.ADMIN.getId();
            }
        }
        return false;
    }
}
